package com.music.service.Impl;

import com.music.mapper.UserMapper;
import com.music.service.UserService;
import com.music.vo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Random;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 用户服务实现类，处理业务逻辑
 */
@Service
@Transactional // 启用事务管理
public class UserServiceImpl implements UserService {

    private final UserMapper userMapper;
    private final BCryptPasswordEncoder passwordEncoder;

    public UserServiceImpl(UserMapper userMapper, BCryptPasswordEncoder passwordEncoder) {
        this.userMapper = userMapper;
        this.passwordEncoder = passwordEncoder;
    }

    /**
     * 用户注册逻辑
     * @param user 用户对象（包含用户名、密码等字段）
     */
    @Override
    public void register(User user) {
        // 验证用户名唯一性
        if (userMapper.selectByUsername(user.getUsername()) != null) {
            throw new RuntimeException("用户名已存在");
        }

        // 加密密码
        String hashedPassword = passwordEncoder.encode(user.getPassword());
        user.setPassword(hashedPassword);

        userMapper.insertUser(user);
    }

    /**
     * 用户登录验证
     * @param username 用户名
     * @param password 密码
     * @return 验证通过的用户对象
     */
    @Override
    public User login(String username, String password) {
        User user = userMapper.selectByUsername(username);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new RuntimeException("密码错误");
        }

        return user;
    }

    /**
     * 手机号和密码登录验证
     * @param phoneNumber 手机号
     * @param password 密码
     * @return 验证通过的用户对象
     */
    @Override
    public User loginByPhone(String phoneNumber, String password) {
        User user = userMapper.selectByPhoneNumber(phoneNumber);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }

        if (!passwordEncoder.matches(password, user.getPassword())) {
            throw new RuntimeException("密码错误");
        }

        return user;
    }

    /**
     * 更新用户信息
     * @param user 包含用户ID和更新字段的用户对象
     */
    @Override
    public void updateUser(User user) {
        // 如果更新密码，需要重新加密
        if (user.getPassword() != null && !user.getPassword().isEmpty()) {
            String hashedPassword = passwordEncoder.encode(user.getPassword());
            user.setPassword(hashedPassword);
        }

        userMapper.updateUser(user);
    }

    /**
     * 根据用户名查询用户（用于验证唯一性）
     * @param username 用户名
     * @return 用户对象（存在则返回，否则null）
     */
    @Override
    public User selectByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    /**
     * 更新用户头像
     * @param file 上传的头像文件
     * @param userId 用户 ID
     * @return 头像文件的 URL
     * @throws IOException 处理文件时可能抛出的异常
     */
    @Override
    public String updateAvatar(MultipartFile file, Integer userId) throws IOException {
        // 检查上传的文件是否为空
        if (file.isEmpty()) {
            // 若文件为空，抛出运行时异常
            throw new RuntimeException("上传的文件为空");
        }
        // 定义存储头像的目录
        String uploadDir = "uploads/avatars";
        // 将目录字符串转换为 Path 对象
        Path uploadPath = Paths.get(uploadDir);
        // 检查存储头像的目录是否存在
        if (!Files.exists(uploadPath)) {
            // 若目录不存在，则创建该目录及其所有父目录
            Files.createDirectories(uploadPath);
        }
        // 获取上传文件的原始文件名
        String originalFilename = file.getOriginalFilename();
        // 从原始文件名中提取文件扩展名
        String fileExtension = originalFilename.substring(originalFilename.lastIndexOf("."));
        // 生成一个唯一的文件名，使用 UUID 确保文件名的唯一性
        String newFileName = UUID.randomUUID().toString() + fileExtension;
        // 将新文件名与存储目录结合，形成完整的文件路径
        Path filePath = uploadPath.resolve(newFileName);
        // 将上传的文件保存到指定的文件路径
        file.transferTo(filePath.toFile());
        // 根据用户 ID 从数据库中查询用户信息
        User user = userMapper.selectById(userId);
        // 检查查询到的用户是否存在
        if (user == null) {
            // 若用户不存在，抛出运行时异常
            throw new RuntimeException("用户不存在");
        }
        // 将新头像文件名转换为字节数组，并设置到用户对象的头像字段中
        user.setAvatar(newFileName.getBytes());
        // 调用 userMapper 的 updateUser 方法更新数据库中的用户信息
        userMapper.updateUser(user);
        // 返回头像文件的 URL，该 URL 可用于在前端显示头像
        return "/uploads/avatars/" + newFileName;
    }


    // 新增管理员相关方法实现
    @Override
    public User selectById(Integer userId) {
        return userMapper.selectById(userId);
    }

    @Override
    public List<User> selectAllUsers() {
        return userMapper.selectAllUsers();
    }

    @Override
    public void freezeUser(Integer userId) {
        User user = userMapper.selectById(userId);
        if (user != null) {
            user.setStatus(1); // 设置为禁用状态
            userMapper.updateUser(user);
        }
    }

    @Override
    public void unfreezeUser(Integer userId) {
        User user = userMapper.selectById(userId);
        if (user != null) {
            user.setStatus(0); // 设置为正常状态
            userMapper.updateUser(user);
        }
    }
}